import BaseTank from "./BaseTank";
import { Globals, Dir } from "./Global";
import MapLayer from "./MapLayer";
import UpdateInfomations from "./UpdateInfomations";
import Game from "./Game";
import AudioMgr from "./AudioMgr";
import { log_debug } from "./Utils";

const {ccclass, property} = cc._decorator;

@ccclass
export default class PlayerTank extends BaseTank {
    @property(cc.SpriteFrame)
    frames: cc.SpriteFrame[] = [];

    @property(cc.Node)
    ring: cc.Node = null;

    _isInvincible: boolean;
    _movingAnimation: string;

    init() {
        this.blood = 3;
        this.isEnemy = false;
        this.mapLayer = cc.find("/Canvas/GameLayer/MapLayer").getComponent(MapLayer);

        if (Globals.DEBUG_PLAYER_TANK) {
            this.level = 3;
            this.bulletCount = 3;
        }

        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this._onKeyDown, this);
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this._onKeyUp, this);

        this.reset();
    }

    update(dt: number) {
        if (!this.canMove) {
            return;
        }

        // 等级决定移动速度
        if (this.autoMoving) {
            let speed = 25 + this.level * 2;
            let realStep = speed * dt;
            this._autoMoving(realStep);
        }

        // 实时检测是否拾取道具
        if (this._isCollisionWithProp()) {
            this.mapLayer.takeProp();
        }        
    }

    /*
        等级0 默认
        等级1 1颗星 增加移速+增加子弹+升级外形
        等级2 2颗星 增加移速+击穿冰块+升级外形
        等级3 3颗星 增加移速+增加子弹+升级外形
        等级3 4颗星及以上 生命+1
    */
    updateLevel() {
        if (this.level < 3) {
            // 升级外形
            this.level++;
            this.getComponent(cc.Sprite).spriteFrame = this.frames[this.level];
            // 增加子弹
            if (this.level == 1 || this.level == 3) {
                this.bulletCount++;
            }
        } else {
            // 生命+1
            ++this.blood;
            cc.find("/Canvas/GameLayer/Infomations").getComponent(UpdateInfomations).updatePlayerBlood(this.blood-1);   
        }
    }

    reset() {
        this.getComponent(cc.Sprite).spriteFrame = this.frames[this.level];
        this._isInvincible = true;
        this._setDir(Dir.UP);
        this.node.setPosition(Globals.PLAYER1);
        this.getComponent(cc.Animation).play("star");
        cc.find("/Canvas/GameLayer/Infomations").getComponent(UpdateInfomations).updatePlayerBlood(this.blood-1);
    }

    _invincibleStatus() {
        this._isInvincible = true;
        this.ring.active = true;
        let animation = this.ring.getComponent(cc.Animation);
        animation.play("ring");
        // 5秒后取消无敌状态
        this.scheduleOnce(() => {
            this._isInvincible = false;
 
            animation.stop();
            this.ring.active = false;
        }, Globals.INVINCIBLE_TIME);  
    }

    // star动画播放完后执行
    afterStarAnimationCompleted() {
        this.canMove = true;
        this._playMovingAnimation();
        this._invincibleStatus();
    }

    onInvincible() {
        this._invincibleStatus();
    }

    shoot() {
        if (!this.canMove) {
            return;
        }
        // 等级决定子弹速度
        let flag = this.mapLayer.createBullet(this.dir, this.node.position, (this.level+1)*2, this);
        if (flag) {
            cc.find("/Game/AudioMgr").getComponent(AudioMgr).playAudio("shoot", false);
        }
    }

    move(dir: Dir) {
        if (!this.canMove) {
            return;
        }

        if (!this.autoMoving) {
            cc.find("/Game/AudioMgr").getComponent(AudioMgr).playAudio("player_move", true);
            this.autoMoving = true;
        }

        this._setDir(dir);
        this._playMovingAnimation();
    }

    moveStop() {
        if (!this.canMove) {
            return;
        }

        this.autoMoving = false;
        cc.find("/Game/AudioMgr").getComponent(AudioMgr).stopAudio("player_move");
        this._playerMovingAnimationStop();
    }

    disBlood() {
        if (Globals.DEBUG_PLAYER_TANK) {
            return;
        }

        if (this._isInvincible){
            return;
        }

        if (--this.blood == 0) {
            // 播放死亡动画
            this.getComponent(cc.Animation).play("blast");
            // 该局结束
            this.gameOver();
        } else {
            this.reset();
            this.level = 0;
            cc.find("/Canvas/GameLayer/Infomations").getComponent(UpdateInfomations).updatePlayerBlood(this.blood - 1);
        }
    }

    // 播放从左到右的game over动画
    gameOver() {
        this.node.active = false;
        cc.find("/Game/AudioMgr").getComponent(AudioMgr).stopAudio("player_move");
        this.node.destroy();

        let visableSize = cc.view.getVisibleSize();
        let gameOverNode = cc.find("/Canvas/External/gameover_left");
        gameOverNode.active = true;
        gameOverNode.setPosition(-visableSize.width / 2 - gameOverNode.width / 2, -94);

        // 右移动画
        cc.tween(gameOverNode).to(1.5, {x:-35, y:-94}).delay(1).call(() => {
            // 播放上升动画
            cc.find("/Game").getComponent(Game).gameOver();
        }).start();
    }

    _playMovingAnimation() {
        this._movingAnimation = "moving" + this.level;
        this.getComponent(cc.Animation).play(this._movingAnimation);
    }

    _playerMovingAnimationStop() {
        this.getComponent(cc.Animation).stop(this._movingAnimation);
    }

    _setDir(dir: Dir) {
        if (this.dir == dir) {
            return;
        }

        let oldPosition = this.node.position;

        this._adjustPosition();

        if (this._isCollisionWithBlock() || this._isCollisionWithMap() || this._isCollisionWithTank()) {
            this.node.position = oldPosition;
        }

        // 弧度转方向
        this.dir = dir;
        this.node.angle = -90 * this.dir;

        // 产生贴图
        this._playMovingAnimation();
    }

    _autoMoving(realStep) {
        let oldPosition = this.node.position;

        switch (this.dir) {
            case Dir.LEFT:
                this.node.x -= realStep;
                break;
            case Dir.RIGHT:
                this.node.x += realStep;
                break;
            case Dir.DOWN:
                this.node.y -= realStep;
                break;
            case Dir.UP:
                this.node.y += realStep;
                break;
            default:
                break;
        }

        if (this._isCollisionWithBlock() || this._isCollisionWithMap() || this._isCollisionWithTank()) {
            this.node.position = oldPosition;
        }
    }

    _onKeyDown(event: {keyCode: cc.macro.KEY;}) {
        if (!this.canMove) {
            return;
        }

        switch (event.keyCode) {
            case cc.macro.KEY.a:
                this.move(Dir.LEFT);
                break;
            case cc.macro.KEY.d:
                this.move(Dir.RIGHT);
                break;
            case cc.macro.KEY.w:
                this.move(Dir.UP);
                break;
            case cc.macro.KEY.s:
                this.move(Dir.DOWN);
                break;
            case cc.macro.KEY.j:
                this.shoot();
                break;
            default:
                break;
        }
    }

    _onKeyUp(event: {keyCode: cc.macro.KEY;}) {
        if (!this.canMove) {
            return;
        }

        switch (event.keyCode) {
            case cc.macro.KEY.a:
            case cc.macro.KEY.d:
            case cc.macro.KEY.w:
            case cc.macro.KEY.s:
                this.moveStop();
                break;
            default:
                break;
        }
    }
}
